<?php

namespace app\qsapi\service;

use app\admin\model\yun\YunPhoneCdkBatch;
use app\admin\model\yun\YunPhoneCdkExchangeRecord;
use app\qsapi\model\yunPhone\YunPhoneCdkCode;
use app\qsapi\model\yunPhone\YunPhoneOrder;
use app\qsapi\model\yunPhone\YunPhoneOrderMachine;
use app\qsapi\model\yunPhone\YunPhoneUserMachine;
use think\cache\driver\Redis;
use think\Db;
use think\Exception;

class YunPhoneOrderService extends BaseService
{

    /**
     * @Notes:下单
     * @Interface yunMakeOrder
     * @param $member_id
     * @param $param
     * @return array
     */
    public function yunMakeOrder($member_id, $param): array
    {
        //=======用户防刷操作redis=======
        $redis = new Redis(getRedisConfig());
        if ($redis->get('user_yun_make_order:' . $member_id)) {
            return api_message([], '操作过于频繁', 0);
        }
        $redis->set('user_yun_make_order:' . $member_id, $member_id, 5);
        //=======用户防刷操作redis==========
        if (empty($param['order_type'])) return api_message([], '参数错误', 0);
        $cdk = $param['cdk'] ?? '';
        if (empty($cdk)) return api_message([], '请输入兑换CDK', 0);
        if ($param['order_type'] == 2 && empty($param['user_device_id'])) {
            return api_message([], "请选择续费的设备", 0);
        }
        //判断CDK是否有效
        $cdkResult = YunPhoneCdkCode::where(['cdk' => $cdk, 'status' => 1, 'mark' => 1])->find();
        if (empty($cdkResult)) return api_message([], '无效的CDK', 0);
        if ($cdkResult['is_active'] == 1) return api_message([], '当前CDK已被激活过', 0);
        if ($cdkResult['start_time'] > date('Y-m-d H:i:s')) return api_message([], 'CDK还未到使用时间', 0);
        if ($cdkResult['end_time'] < date('Y-m-d H:i:s')) return api_message([], 'CDK已过期', 0);

        $yunData = [];
        $userDeviceId = $param['user_device_id'] ?? '';
        if ($param['order_type'] == 2) {
            //yun_type == 2  续费操作
            if (empty($userDeviceId)) return api_message([], '请选择续费的设备', 0);
            //查询此设备
            $yunData = (new YunPhoneService)->getYunPhoneUserList($member_id, $userDeviceId);
            if ($yunData['code'] != 1) return api_message([], $yunData['message'] ?? '查询设备失败!', 0);
            if (empty($yunData['data']['records'])) return api_message([], '无此设备', 0);
            $status = $yunData['data']['records']['0']['status'] ?? 0;
            if ($status == -50) return api_message([], '设备已注销', 0);
            if ($status == -10) return api_message([], '设备已过期', 0);
        }

        Db::startTrans();
        try {
            $orderModel = new YunPhoneOrder();
            $insert = [
                'member_id'   => $member_id,
                'order_num'   => self::generateOrderNum($member_id),
                'num'         => $param['num'] ?? 1,
                'status'      => 1,
                'order_type'  => $param['order_type'],
                'create_time' => date("Y-m-d H:i:s"),
                'client_ip'   => get_client_ip(),
                'cdk'         => $cdk,
                'good_code'   => env('YUN_PHONE_API.ITEM_CODE'),
            ];
            $id = $orderModel->insertGetId($insert);
            if (!$id) throw new Exception('yunMakeOrder::创建订单报错' . $orderModel->getError(), 0);
            if ($param['order_type'] == '2') {
                $result = (new YunPhoneCdkCode())->alias('a')
                    ->leftJoin('yun_phone_cdk_batch b', 'a.batch_id=b.id')
                    ->field('a.id,b.duration')
                    ->where(['a.cdk' => $cdk, 'a.status' => 1, 'a.mark' => 1, 'a.is_active' => 0, 'b.status' => 1, 'b.mark' => 1])->find();
                if (empty($result)) throw new Exception("CDK兑换信息为空\r\n");
                $duration = $result['duration'] ?? 0;
                if (empty($duration)) {
                    throw new Exception("CDK批次兑换时长:{$duration}为空\r\n");
                }
                $validEndTime = $yunData['data']['records'][0]['validEndTime'] / 1000;
                $machineModel = new YunPhoneOrderMachine();
                $machine['yun_order_id'] = $id;
                $machine['member_id'] = $member_id;
                $machine['client_ip'] = get_client_ip();
                $machine['type'] = 2;
                $machine['duration'] = $duration;
                $machine['start_time'] = date('Y-m-d H:i:s', $yunData['data']['records'][0]['validStartTime'] / 1000);
                $machine['end_time'] = date('Y-m-d H:i:s', $validEndTime + ($duration * 86400));
                $machine['user_device_id'] = $yunData['data']['records'][0]['userDeviceId'] ?? $userDeviceId;
                $machine['create_time'] = date('Y-m-d H:i:s');
                $id = $machineModel->insertGetId($machine);
                if (!$id) throw new Exception("下单失败！" . $machineModel->getError(), 0);
                YunPhoneUserMachine::where('user_device_id', '=', $userDeviceId)->update(['last_renew_time' => date('Y-m-d H:i:s')]);
            }
            //将CDK状态改为已使用
            $cdkModel = new YunPhoneCdkCode();
            $cdkModel->where(['cdk' => $cdk])->update([
                'member_id' => $member_id,
                'is_active' => 1,
                'use_time'  => date('Y-m-d H:i:s')
            ]);
            //更新CDK兑换记录
            $recordsData = [
                'member_id' => $member_id,
                'cdk'       => $cdk,
                'type'      => $param['order_type'] ?? 1,
                'batch_id'  => $cdkResult['batch_id'] ?? 0,
            ];
            if ($param['order_type'] == '2') $recordsData['user_device_id'] = $userDeviceId;
            (new YunPhoneCdkExchangeRecord())->insertGetId($recordsData);
            $data = ['order_num' => $insert['order_num']];
            //将订单号写入redis队列中
            $redis->lPush('YUN_PHONE_ORDER_QUEUE', $data['order_num']);
            Db::commit();
            return api_message($data, '下单成功！');
        } catch (Exception $e) {
            Db::rollback();
            write_log('INFO', 'YunPhoneOrderService::yunMakeOrder' . $e->getMessage(), 'YunPhoneOrderMachine', true);
            return api_message([], $e->getMessage(), 0);
        }
    }


    /**
     * Notes: 生成订单号
     * User: liubaoqiang
     * DateTime: 2024/12/11 14:06
     * @param $userId
     * @return string|void
     */
    private static function generateOrderNum($userId)
    {
        $orderNum = "YP_" . date("Ymd") . $userId . str_pad(rand(1, 9999), 4, 0, STR_PAD_LEFT);
        //查询订单号是否存在
        $exit = YunPhoneOrder::where(['order_num' => $orderNum])->find();
        if (!empty($exit)) {
            self::generateOrderNum($userId);
        } else {
            return $orderNum;
        }
    }

    /**
     * Notes: CDK兑换列表
     * User: liubaoqiang
     * DateTime: 2024/12/17 11:17
     */
    public function getYunPhoneExchangeList(int $member_id = 0): array
    {
        if (empty($member_id)) return api_message([], '用户参数错误！', 0);
        $limit = request()->param('limit', 10);
        $model = new YunPhoneCdkExchangeRecord();
        $list = $model->alias('a')
            ->leftJoin('yun_phone_cdk_batch b', 'a.batch_id=b.id')
            ->field('a.*,b.duration')
            ->where('a.member_id', '=', $member_id)
            ->order('id desc')
            ->paginate($limit);
        foreach ($list as  &$item){
            $item['type'] = YunPhoneOrder::ORDER_TYPE[$item['type']] ?? '';
        }
        return api_message($list->toArray());
    }
}
